home *** CD-ROM | disk | FTP | other *** search
-
- ;
- ; Copyright (c) 1988 Commodore-Amiga, Inc.
- ;
- ; Executables based on this information may be used in software
- ; for Commodore Amiga computers. All other rights reserved.
- ;
- ; This information is provided "as is"; no warranties are made.
- ; All use is at your own risk, and no liability or responsibility is assumed.
- ;
-
- ;==============================================================================
- ; An example of Amiga assembly language programming to complement the notes
- ; provided for the Developers Conference. Written by Steve Beats, 4/26/88.
- ;
- ; This is just a simple letter square program that allows you to slide letters
- ; around in a grid with a view to getting them in the right order. Use the
- ; right mouse button to shuffle the letters and the left mouse button to put
- ; them back in order again. A count of shuffles versus moves is kept so you
- ; have some idea of how well you are doing.
- ;
- ; It's left as an excercise for the reader to detect when game is over :-)
- ;
- ; It would probably be a good idea to re-organise the source into separate,
- ; smaller modules, but I left it as one humongous source file so that I didn't
- ; have to get bogged down in linker details. To assemble with the Metacomco
- ; assembler, use the following command:-
- ;
- ; assem example.asm -o example.o -i INCLUDE: -c=W150000
- ;
- ; where INCLUDE: is assigned to the directory containing the standard includes.
- ; Linking is also simple, just use the following:-
- ;
- ; blink example.o to example lib INCLUDE:amiga.lib
- ;
- ;==============================================================================
- SECTION example,CODE
-
- NOLIST
- INCLUDE "exec/types.i"
- INCLUDE "exec/memory.i"
- INCLUDE "exec/ports.i"
- INCLUDE "intuition/intuition.i"
- LIST
-
- ; first we define all the global data we will require for this program
- STRUCTURE globals,0
- APTR SysLib exec library
- APTR IntLib intuition library
- APTR GfxLib graphics library
- APTR DosLib dos library
-
- APTR MainWindow pointer to the window
- LONG WaitMask mask of bits to wait for
- APTR TheRastPort windows rastport
-
- APTR GameArray tile memory
- UWORD SpaceX x co-ordinate of the hole
- UWORD SpaceY y co-ordinate of the hole
- ULONG Shuffles number of shuffles we've done
-
- APTR TextBuff for making numbers
- STRUCT RND,8 current random seed
-
- UWORD Closed flag, user hit close gadget
- LABEL globals_SIZEOF
-
- ; now define data structures for private stuff used within the program
- STRUCTURE tile,0
- UWORD t_x position of tile
- UWORD t_y
- UWORD t_type 0=no tile else the letter
- UWORD t_moved flag for shuffling
- LABEL tile_SIZEOF
-
- ; next, define all library routines we will be calling as external symbols
- XREF _AbsExecBase,_LVOOpenLibrary,_LVOCloseLibrary
- XREF _LVOAllocMem,_LVOFreeMem
- XREF _LVOWait,_LVOGetMsg,_LVOReplyMsg
-
- XREF _LVOOpenWindow,_LVOCloseWindow
- XREF _LVOBeginRefresh,_LVOEndRefresh
- XREF _LVOModifyIDCMP,_LVOCurrentTime
- XREF _LVODisplayBeep
-
- XREF _LVOSetAPen,_LVOSetDrMd,_LVOMove
- XREF _LVOText,_LVORectFill
-
- ;==============================================================================
- ; The entry point of the program. Reserve space for globals on the stack.
- ;==============================================================================
- Start moveq.l #(globals_SIZEOF/2)-1,d0
- ClrStack clr.w -(sp)
- dbra d0,ClrStack
- movea.l sp,a5 a5 always points to globals
- move.l _AbsExecBase,SysLib(a5) stash exec base
-
- lea.l Libraries(pc),a0 open all our libraries
- bsr OpenLibs
- tst.l d0 did it work ?
- beq Exit no, exit now
-
- lea.l MemTable(pc),a0 allocate all our static memory
- bsr AllocMemory
- tst.l d0 did it work ?
- beq Exit no, exit now
-
- movea.l IntLib(a5),a6 seed random number generator
- lea.l RND(a5),a0
- lea.l RND+4(a5),a1
- jsr _LVOCurrentTime(a6)
-
- lea.l MyWindow(pc),a0 open the window
- move.l a0,d0
- add.l d0,nw_Title(a0) relocate title reference
- jsr _LVOOpenWindow(a6)
- move.l d0,MainWindow(a5) did it open OK ?
- beq Exit no, exit now
-
- movea.l d0,a0 stash important values
- move.l wd_RPort(a0),TheRastPort(a5)
- moveq.l #0,d0
- movea.l wd_UserPort(a0),a1
- move.b MP_SIGBIT(a1),d1
- bset.l d1,d0
- move.l d0,WaitMask(a5) bit mask we will wait on
-
- bsr InitTiles initialise tile memory
- moveq.l #0,d0 so we redraw OK first time thru
- bsr RefreshWindow and draw the tiles
-
- ;==============================================================================
- ; The main loop of the program. Wait on some kind of input and dispatch it.
- ;==============================================================================
- MainLoop movea.l SysLib(a5),a6 wait for something to happen
- move.l WaitMask(a5),d0
- jsr _LVOWait(a6)
-
- NextMessage movea.l MainWindow(a5),a0
- movea.l wd_UserPort(a0),a0 woken up, get a message
- jsr _LVOGetMsg(a6)
- tst.l d0
- beq.s MainLoop no message, wait again
-
- movea.l d0,a2 save message pointer
- move.l im_Class(a2),d0 search table for this class
- lea.l Dispatch(pc),a0
- DispatchLoop move.l (a0)+,d1 get function offset
- beq.s DispatchDone unknown message!
- cmp.l (a0)+,d0 was this the correct one ?
- bne.s DispatchLoop no, check the next one
-
- movea.l a2,a0 message to a0 for the routine
- jsr Dispatch(pc,d1.l) call correct routine
- DispatchDone movea.l a2,a1 reply the message
- jsr _LVOReplyMsg(a6)
- tst.w Closed(a5) are we finished ?
- bne.s Exit yes
- bra.s NextMessage no, look for another message
-
- ;==============================================================================
- ; a dispatch table containing an offset to a routine and the IDCMP class
- ; required for that routine to be called. Zero terminates the list.
- ;==============================================================================
- Dispatch DC.L HandleClick-Dispatch,MOUSEBUTTONS
- DC.L RefreshWindow-Dispatch,REFRESHWINDOW
- DC.L ShuffleOnce-Dispatch,INTUITICKS
- DC.L CloseDown-Dispatch,CLOSEWINDOW
- DC.L 0
-
- ;==============================================================================
- ; Program exits here.
- ;==============================================================================
- Exit move.l MainWindow(a5),d0 close window if it opened
- beq.s Exit_1 no window to close
- movea.l d0,a0
- movea.l IntLib(a5),a6 using intuition library
- jsr _LVOCloseWindow(a6)
-
- Exit_1 lea.l MemTable(pc),a0 free any allocated memory
- bsr FreeMemory
- lea.l Libraries(pc),a0 close any opened libraries
- bsr CloseLibs
- lea.l globals_SIZEOF(sp),sp free stack space
- moveq.l #0,d0 and do a non error return
- rts
-
-
- ;==============================================================================
- ; CloseDown()
- ;
- ; Just sets the Closed state variable so we exit the program
- ;==============================================================================
- CloseDown move.w #-1,Closed(a5)
- rts
-
- ;==============================================================================
- ; RefreshWindow( firsttime )
- ; d0
- ;
- ; Completely redraws everything in the window, border, tiles and such. If
- ; firsttime == 0 then the Begin and End refresh calls are not made.
- ;==============================================================================
- RefreshWindow move.l a6,-(sp)
- move.l d0,-(sp) is this first time
- beq.s 10$ yes, dont beginrefresh
- movea.l IntLib(a5),a6 using intuition
- movea.l MainWindow(a5),a0 begin refresh sequence
- jsr _LVOBeginRefresh(a6) to fix up layers
-
- 10$ bsr DrawBorder do the border outline
- bsr DrawAllTiles and all the tiles
- bsr ShuffleCount and the score area
- move.l (sp)+,d0 was this first time ?
- beq.s 20$ yes, don't end refresh
-
- movea.l MainWindow(a5),a0
- jsr _LVOEndRefresh(a6) refresh done
- 20$ move.l (sp)+,a6
- rts
-
- ;==============================================================================
- ; HandleClick( message )
- ; a0
- ;
- ; Moves a tile based on the position of the given MOUSEBUTTONS message.
- ; Left mouse button down will attempt to move the tiles
- ; Left mouse button up will do nothing
- ; Right mouse button down will start shuffling the tiles (switch on INTUITICKS)
- ; Right mouse button up will stop shuffling the tiles (switch off INTUITICKS)
- ;==============================================================================
- HandleClick movem.l a2/a6,-(sp)
- movea.l a0,a2 stash message address
- move.w im_Code(a2),d1 check for left or right button
- cmpi.w #IECODE_LBUTTON!IECODE_UP_PREFIX,d1
- beq.s ClickDone nothing for left button up
- cmpi.w #IECODE_LBUTTON,d1
- beq.s HandleLeft
-
- ; it was a right button click, if down turn on INTUITICKS in the IDCMP port
- move.l #IDCMPFLAGS!INTUITICKS,d0 assume down
- cmpi.w #IECODE_RBUTTON!IECODE_UP_PREFIX,d1
- bne.s 10$ assumption correct
- move.l #IDCMPFLAGS,d0 stop shuffling now
- 10$ movea.l IntLib(a5),a6 using intuition
- movea.l MainWindow(a5),a0
- jsr _LVOModifyIDCMP(a6) set new IDCMP values
- bra.s ClickDone
-
- ; user clicked on a tile, move it if the chosen tile was a legal selection
- HandleLeft movem.w im_MouseX(a2),d0/d1 convert d0/d1 to tile x,y
- subi.w #9,d0 allow for border
- bmi.s ClickError out of range
- ext.l d0
- divs #35,d0
- cmpi.w #4,d0
- bge.s ClickError
-
- subi.w #39,d1 allow for offset to grid
- bmi.s ClickError out of range
- ext.l d1
- divs #17,d1
- cmpi.w #4,d1
- bge.s ClickError
-
- bsr MoveTiles move correct tiles
- subq.l #1,Shuffles(a5) subtract from shuffle count
- bsr ShuffleCount and update it on the screen
- bra.s ClickDone
-
- ClickError bsr Bleep bleep display for error
-
- ClickDone movem.l (sp)+,a2/a6
- rts
-
- ;==============================================================================
- ; ShuffleOnce()
- ;
- ; Performs one shuffle on the tiles and updates the display to reflect changes
- ;==============================================================================
- ShuffleOnce moveq.l #3,d0 figure which tile to move
- bsr Random
- move.w d0,-(sp) and save it
- moveq.l #1,d0 now see if it's a row or col
- and.l Shuffles(a5),d0 columns on even iterations
- beq.s ShuffleColumn we want to move up or down
-
- ; execute this code when we are sliding the tiles left or right into the space
- ; the row number will be the same as the space but the column number can't be.
- move.w SpaceY(a5),d1 tile is in this row
- move.w (sp)+,d0 get the column number
- cmp.w SpaceX(a5),d0 is it the same
- bne.s DoShuffle no, so it's valid now
- addq.w #1,d0 yes, so bump to the next tile
- bra.s DoShuffle go move it
-
- ; execute this code when we are sliding the tiles up or down into the space
- ; the column number will be the same as the space but the row number can't be.
- ShuffleColumn move.w SpaceX(a5),d0 tile is in this column
- move.w (sp)+,d1 get row number
- cmp.w SpaceY(a5),d1 is it the same
- bne.s DoShuffle no, so it's valid now
- addq.w #1,d1 yes, so bump to the next tile
-
- ; we have chosen the tile we want to move, update shuffle count and then call
- ; MoveTiles to move 1 or more tiles in the right direction (into the space)
- DoShuffle bsr MoveTiles move relevant tiles
- addq.l #1,Shuffles(a5) add one to number of shuffles
- bsr ShuffleCount print current shufflecount
- rts
-
- ;==============================================================================
- ; Bleep()
- ;
- ; Just does a DisplayBeep on the screen this window is in
- ;==============================================================================
- Bleep move.l a6,-(sp)
- movea.l IntLib(a5),a6 using intuition
- movea.l MainWindow(a5),a0 find the screen to beep
- movea.l wd_WScreen(a0),a0
- jsr _LVODisplayBeep(a6) do the flash
- move.l (sp)+,a6 and that's all
- rts
-
- ;==============================================================================
- ; ShuffleCount()
- ;
- ; Displays current number of shuffles in the top portion of the screen.
- ;==============================================================================
- ShuffleCount movem.l d2/d3/a6,-(sp)
- movea.l GfxLib(a5),a6 using graphics library
-
- movea.l TheRastPort(a5),a1 set pen to background color
- moveq.l #0,d0
- jsr _LVOSetAPen(a6)
-
- moveq.l #10,d0 erase the score area
- moveq.l #13,d1
- moveq.l #80,d2
- moveq.l #22,d3
- movea.l TheRastPort(a5),a1
- jsr _LVORectFill(a6)
-
- moveq.l #15,d0 move to place for score
- moveq.l #20,d1
- movea.l TheRastPort(a5),a1
- jsr _LVOMove(a6)
-
- movea.l TheRastPort(a5),a1 set pen to black
- moveq.l #2,d0
- jsr _LVOSetAPen(a6)
-
- movea.l TheRastPort(a5),a1 and drawmode to jam1
- moveq.l #RP_JAM1,d0
- jsr _LVOSetDrMd(a6)
-
- movea.l TextBuff(a5),a0
- move.l Shuffles(a5),d0 convert shuffles to ascii
- bsr bin2asc32 returns d0 = length
- move.w d0,-(sp) save length for later
- movea.l TextBuff(a5),a0
- movea.l TheRastPort(a5),a1
- jsr _LVOText(a6) write the text out
-
- movea.l TheRastPort(a5),a1 set pen to white now
- moveq.l #1,d0
- jsr _LVOSetAPen(a6)
-
- moveq.l #13,d0 move to place for score
- moveq.l #19,d1 offset it 2 in x and 1 in y
- movea.l TheRastPort(a5),a1
- jsr _LVOMove(a6)
-
- move.w (sp)+,d0 get back the text length
- movea.l TextBuff(a5),a0 and the text buffer
- movea.l TheRastPort(a5),a1
- jsr _LVOText(a6) write the text out
-
- movem.l (sp)+,d2/d3/a6
- rts
-
- ;=============================================================================
- ; nextplace = bin2asc[nn]( value,buffer )
- ; d0 d0 a0
- ;
- ; converts the given binary value to a null terminated string of ascii digits
- ; in the buffer provided. [nn] can be 08,16 or 32 to handle different sizes.
- ;============================================================================
- bin2asc08 ext.w d0 make bytes into words
- bin2asc16 ext.l d0 make words into a longwords
- bin2asc32 movem.l d2/a2,-(sp)
- movea.l a0,a2 save buffer pointer
- tst.l d0 is number negative ?
- bpl.s bin2asc nope, call main routine
- neg.l d0 yes, so make it positive
- move.b #'-',(a0)+ and output a minus sign
-
- bin2asc lea.l PowersOfTen(pc),a1 point to powers of ten table
-
- ; first we quickly check for the first real digit we will be using (non 0)
- 10$ move.l (a1)+,d2 get next power of ten
- beq.s 40$ value was zero to start
- cmp.l d2,d0 is the number this big ?
- blt.s 10$ no, keep searching
-
- moveq.l #'0',d1 current digit value
- 20$ addq.w #1,d1 update this digit
- sub.l d2,d0 subtract current pwr of 10
- 30$ cmp.l d2,d0 can we do it again ?
- bge.s 20$ yes, keep going
- move.b d1,(a0)+ no, save the current digit
- moveq.l #'0',d1 digit value back to '0' now
- move.l (a1)+,d2 get next power of 10
- bne.s 30$ and check against number
- bra.s 50$ all done. terminate string
-
- 40$ move.b #'0',(a0)+ store an ascii 0
- 50$ clr.b (a0) terminate the string
- move.l a0,d0 compute length
- sub.l a2,d0
- movem.l (sp)+,d2/a2 and return
- rts
-
- PowersOfTen DC.L 1000000000,100000000,10000000,1000000
- DC.L 100000,10000,1000,100,10,1,0
-
-
- ;==============================================================================
- ; MoveTiles( xtile, ytile )
- ; d0 d1
- ;
- ; Given a tile that was clicked on or a tile that was chosen by ShuffleOnce,
- ; moves the appropriate number of tiles towards the space and renders them.
- ;==============================================================================
- MoveTiles movem.l d2-d3,-(sp)
- cmp.w SpaceX(a5),d0 consistency check
- bne.s Check2 only row or column...
- cmp.w SpaceY(a5),d1 ...can be the same...
- beq MoveError ...as the space
- bra.s MovingColumn tiles are sliding up or down
-
- Check2 cmp.w SpaceY(a5),d1 but at least one of them...
- bne.s MoveError ...must be the same
-
- ; executes this code when we are sliding the tiles along a row into the space
- moveq.l #tile_SIZEOF,d2 array increment when moving
- move.w d0,d3 see how many to move
- sub.w SpaceX(a5),d3
- bpl.s DoMove
- neg.w d2 have to go backwards
- neg.w d3
- bra.s DoMove
-
- ; executes this code when we are sliding the tiles up or down into the space
- MovingColumn moveq.l #4*tile_SIZEOF,d2 array increment when moving
- move.w d1,d3 see how many tiles to move
- sub.w SpaceY(a5),d3
- bpl.s DoMove
- neg.w d2 have to go backwards
- neg.w d3
-
- ; gets here with d2 containing the array increment for moving from one tile
- ; to the next and d3 containing the number of tiles affected ( 1 to 3 tiles)
- ; first, we set up a0 pointing to the tile that contains the space.
- DoMove movem.w d0/d1,-(sp) save tile that becomes space
- movem.w SpaceX(a5),d0/d1 we start from the space
- mulu.w #tile_SIZEOF,d0 get tile x array position
- mulu.w #4*tile_SIZEOF,d1 get tile y array position
- add.l d1,d0 d0 = offset into array
- movea.l GameArray(a5),a0
- adda.l d0,a0 a0 points to the space tile
- subq.w #1,d3 fix up count for dbra
-
- MoveNextTile move.b t_type(a0,d2.w),t_type(a0) slide a tile into space
- move.w #1,t_moved(a0) mark this one as changed
- lea.l 0(a0,d2.w),a0 move to the other tile
- dbra d3,MoveNextTile and carry on if more
- clr.b t_type(a0) now mark this one as the space
- move.w #1,t_moved(a0) and mark it as moved
-
- move.l (sp)+,SpaceX(a5) set up the new space
- bsr DrawMovedTiles re-draw the ones that moved
- bra.s MoveComplete
- MoveError bsr Bleep beep display for errors
- MoveComplete movem.l (sp)+,d2-d3
- rts
-
- ;==============================================================================
- ; DrawBorder()
- ;
- ; Draws the border around the playing area.
- ;==============================================================================
- DrawBorder movem.l d2-d6,-(sp)
- movea.l MainWindow(a5),a0 get pointer to a window
- moveq.l #0,d0 x start
- move.w wd_Height(a0),d1 y start
- subi.w #75,d1
- move.w wd_Width(a0),d2 width
- moveq.l #75,d3 height
- moveq.l #1,d4 border color
- moveq.l #0,d5 middle color
- moveq.l #3,d6 border width
- bsr SpecialBox
- movem.l (sp)+,d2-d6
- rts
-
- ;==============================================================================
- ; InitTiles()
- ;
- ; Initialises the tile array with tile positions and letters to go in them.
- ;==============================================================================
- InitTiles movem.l d2-d3/a2,-(sp)
- movea.l GameArray(a5),a0 a0 points to tile data
- lea.l 15*tile_SIZEOF(a0),a0 point to the last tile
- lea.l Letters(pc),a1 a1 points to current letter
- movea.l MainWindow(a5),a2
- moveq.l #3,d3 row counter
- move.w d3,SpaceX(a5) this is where the space is
- move.w d3,SpaceY(a5) when we initialise
- NextRow moveq.l #3,d2 column counter
- NextColumn move.w d2,d0 x pos = col*35+9
- mulu.w #35,d0
- addi.w #9,d0
- move.w d0,t_x(a0)
- move.w d3,d0 y pos = row*17+4
- mulu.w #17,d0
- addq.w #4,d0
- subi.w #75,d0 ypos += wd_Height-75
- add.w wd_Height(a2),d0
- move.w d0,t_y(a0)
- move.b (a1)+,t_type(a0) fill in the letter
- lea.l -tile_SIZEOF(a0),a0 point to previous tile
- dbra d2,NextColumn
- dbra d3,NextRow
- movem.l (sp)+,d2-d3/a2
- rts
-
- ;==============================================================================
- ; DrawAllTiles()
- ;
- ; refreshes tile display by marking all tiles as moved and calls DrawMovedTiles
- ;==============================================================================
- DrawAllTiles movea.l GameArray(a5),a0 get to first tile
- moveq.l #15,d0 doing 16 of them
- 10$ move.w #1,t_moved(a0) mark this one as moved
- lea.l tile_SIZEOF(a0),a0 move to next tile
- dbra d0,10$ drop through to DrawMovedTiles
-
- ;==============================================================================
- ; DrawMovedTiles()
- ;
- ; Redraws any tiles that have a non-zero t_moved field and then clears it.
- ;==============================================================================
- DrawMovedTiles movem.l d2/a2,-(sp)
- movea.l GameArray(a5),a2 point to first tile
- moveq.l #15,d2 have to check all of them
- 10$ tst.w t_moved(a2) was this tile moved
- beq.s 20$ no, so no work
- movea.l a2,a0 yes, so draw it
- bsr.s DrawTile
- clr.w t_moved(a2) mark as not moved now
- 20$ lea.l tile_SIZEOF(a2),a2 point to next tile
- dbra d2,10$ and carry on
- movem.l (sp)+,d2/a2
- rts
-
- ;==============================================================================
- ; DrawTile( tile )
- ; a0
- ;
- ; Draws a tile based on its array position and the letter assigned to that tile
- ;==============================================================================
- DrawTile movem.l d2-d6/a2/a6,-(sp)
- movea.l a0,a2 stash tile address
- movem.w t_x(a2),d0/d1 get tile start position
- moveq.l #32,d2 tile is this wide
- moveq.l #16,d3 and this high
- moveq.l #3,d4 assume a colored tile
- moveq.l #2,d5
- moveq.l #1,d6 border width is 1
- tst.b t_type(a2) is this the blank tile ?
- bne.s 10$ no
- moveq.l #0,d4 just do background color...
- moveq.l #0,d5 ...for the blank tile
- 10$ bsr SpecialBox
- tst.b t_type(a2) is this the blank tile ?
- beq.s TileDrawn yes, no more work to do
-
- movea.l GfxLib(a5),a6 using graphics library
- moveq.l #1,d0 set pen to white
- movea.l TheRastPort(a5),a1
- jsr _LVOSetAPen(a6)
-
- moveq.l #RP_JAM1,d0 only jam 1 color for text
- movea.l TheRastPort(a5),a1
- jsr _LVOSetDrMd(a6)
-
- movem.w t_x(a2),d0/d1 get position to move to
- addi.w #12,d0 add offset for letters
- addi.w #10,d1
- jsr _LVOMove(a6)
-
- lea.l t_type(a2),a0 address of string
- movea.l TheRastPort(a5),a1 to this rastport
- moveq.l #1,d0 drawing 1 character
- jsr _LVOText(a6)
-
- TileDrawn movem.l (sp)+,d2-d6/a2/a6
- rts
-
- ;==============================================================================
- ; SpecialBox( left, top, width, height, bordercolor, boxcolor, thickness)
- ; d0 d1 d2 d3 d4 d5 d6
- ;
- ; Draws a filled in box with a border of the required thickness using the
- ; specified colors. The thickness is doubled in the x direction so that
- ; the border is the same physical width all the way around. As with the
- ; RectFill function, xmin<=xmax and ymin<=ymax.
- ;==============================================================================
- SpecialBox movem.l d2-d3/d6/a6,-(sp)
- movea.l GfxLib(a5),a6 using graphics library
- subq.w #1,d2 convert width and height...
- subq.w #1,d3 ...to absolute co-ordinates
- add.w d0,d2
- add.w d1,d3
- movem.w d0-d3,-(sp) save the box co-ordinates
-
- movea.l TheRastPort(a5),a1
- move.w d4,d0 set pen to border color
- jsr _LVOSetAPen(a6)
- movem.w (sp),d0-d3 get box parameters
- movea.l TheRastPort(a5),a1 and draw it
- jsr _LVORectFill(a6)
-
- movea.l TheRastPort(a5),a1
- move.w d5,d0 set pen to middle color
- jsr _LVOSetAPen(a6)
- movem.w (sp)+,d0-d3 get old box co-ordinates
- add.w d6,d1 ymin += thickness
- sub.w d6,d3 ymax -= thickness
- asl.w #1,d6 double thickness in x
- add.w d6,d0 xmin += thickness*2
- sub.w d6,d2 xmax -= thickness*2
- movea.l TheRastPort(a5),a1 and draw it
- jsr _LVORectFill(a6)
-
- movem.l (sp)+,d2-d3/d6/a6
- rts
-
- ;==============================================================================
- ; RndNum = Random( UpperLimit )
- ; d0 d0
- ;
- ; returns a random integer in the range 0 to UpperLimit-1
- ;============================================================================
- Random move.w d0,-(sp) save range
- beq.s 10$ range of 0 returns 0 always
- bsr.s LongRnd get a longword random number
- clr.w d0 use upper word (it's most random)
- swap d0
- divu.w (sp),d0 divide by range...
- clr.w d0
- swap d0 ...and use remainder for the result
- 10$ addq.l #2,sp scrap range on stack
- rts
-
- ; this is the main random number generation routine. Not user callable
- LongRnd movem.l d2-d3,-(sp)
- movem.l RND(a5),d0/d1 D0=LSB's, D1=MSB's of random number
- andi.b #$0e,d0 ensure upper 59 bits are an...
- ori.b #$20,d0 ...odd binary number
- move.l d0,d2
- move.l d1,d3
- add.l d2,d2 accounts for 1 of 17 left shifts
- addx.l d3,d3 [D2/D3] = RND*2
- add.l d2,d0
- addx.l d3,d1 [D0/D1] = RND*3
- swap d3 shift [D2/D3] additional 16 times
- swap d2
- move.w d2,d3
- clr.w d2
- add.l d2,d0 add to [D0/D1]
- addx.l d3,d1
- movem.l d0/d1,RND(a5) save for next time through
- move.l d1,d0 most random part to D0
- movem.l (sp)+,d2-d3
- rts
-
- ;==============================================================================
- ; Success = OpenLibs( libtable )
- ; d0 a0
- ;==============================================================================
- OpenLibs movem.l a2-a3/a6,-(sp)
- movea.l SysLib(a5),a6 using exec library
- movea.l a0,a2 save working libtable ptr
- movea.l a0,a3 a3 used to calculate name addr
-
- 10$ moveq.l #0,d0 get the version
- move.w (a2)+,d0
- bmi.s LibsOpened return TRUE
- move.w (a2)+,d1 get offset to name
- lea.l 0(a3,d1.w),a1 addr of name in a1
- jsr _LVOOpenLibrary(a6) open the lib
- move.w (a2)+,d1 offset to store at
- move.l d0,0(a5,d1.w) save in global table
- bne.s 10$ OK, go for the next
- LibsOpened movem.l (sp)+,a2-a3/a6 could return 0 if failed above
- rts
-
- ;==============================================================================
- ; CloseLibs( libtable )
- ; a0
- ;==============================================================================
- CloseLibs movem.l a2/a6,-(sp)
- movea.l SysLib(a5),a6 using exec library
- movea.l a0,a2 save libtable pointer
-
- 10$ tst.w (a2)+ end of list ?
- bmi.s LibsClosed yes, quit now
- move.l (a2)+,d0 offset to lower word
- move.l 0(a5,d0.w),d0 get lib pointer
- beq.s LibsClosed that's it, this one failed
- movea.l d0,a1
- jsr _LVOCloseLibrary(a6) close this library
- bra.s 10$ and go for the next
- LibsClosed movem.l (sp)+,a2/a6
- rts
-
- ;==============================================================================
- ; Success = AllocMemory( memtable )
- ; d0 a0
- ;==============================================================================
- AllocMemory movem.l a2/a6,-(sp)
- movea.l SysLib(a5),a6 using exec library
- movea.l a0,a2 stash memtable address
-
- 10$ move.l (a2)+,d0 get size
- bmi.s MemAlloced last entry, return true
- moveq.l #0,d1
- move.w (a2)+,d1 get type
- bset.l #MEMB_CLEAR,d1 clear it too
- jsr _LVOAllocMem(a6) allocate it
- move.w (a2)+,d1 get store offset
- move.l d0,0(a5,d1.w) save it
- bne.s 10$ OK, memory fetched
- MemAlloced movem.l (sp)+,a2/a6 could return 0 if it failed
- rts
-
- ;==============================================================================
- ; FreeMemory( memtable )
- ; a0
- ;==============================================================================
- FreeMemory movem.l a2/a6,-(sp)
- movea.l SysLib(a5),a6 using exec library
- movea.l a0,a2 stash table pointer
-
- 10$ move.l (a2)+,d0 end of list
- bmi.s MemFreed yep, exit now
- move.l (a2)+,d1 offset to lower word
- move.l 0(a5,d1.w),d1 get pointer
- beq.s MemFreed quit! alloc failed on this one
- movea.l d1,a1
- jsr _LVOFreeMem(a6)
- bra.s 10$
- MemFreed movem.l (sp)+,a2/a6
- rts
-
- ;==============================================================================
- ; List of libraries required to run this little demonstration program
- ;==============================================================================
- Libraries DC.W 33,IntName-Libraries,IntLib
- DC.W 33,GfxName-Libraries,GfxLib
- DC.W 33,DosName-Libraries,DosLib
- DC.W -1
- IntName DC.B 'intuition.library',0
- CNOP 0,2
- GfxName DC.B 'graphics.library',0
- CNOP 0,2
- DosName DC.B 'dos.library',0
- CNOP 0,2
-
- ;==============================================================================
- ; list of memory requirements to run the demonstration program
- ;==============================================================================
- MemTable DC.L 16*tile_SIZEOF,(MEMF_PUBLIC<<16)+GameArray
- DC.L 80,(MEMF_PUBLIC<<16)+TextBuff
- DC.L -1
-
- ;==============================================================================
- ; The new window definition for the window that this program will run in
- ;==============================================================================
- WINDOWFLAGS SET WINDOWDEPTH!WINDOWCLOSE!WINDOWDRAG!SIMPLE_REFRESH!ACTIVATE
- WINDOWFLAGS SET WINDOWFLAGS!RMBTRAP
-
- IDCMPFLAGS EQU CLOSEWINDOW!REFRESHWINDOW!MOUSEBUTTONS
-
- MyWindow DC.W 0,0,155,110 left,top,width,height
- DC.B 2,1 detailpen,blockpen
- DC.L IDCMPFLAGS
- DC.L WINDOWFLAGS
- DC.L 0 Gadgets-MyWindow
- DC.L 0 no checkmark
- DC.L Title-MyWindow relative ref to title
- DC.L 0 no screen
- DC.L 0 no bitmap
- DC.W 0,0,0,0 no min or max sizes
- DC.W WBENCHSCREEN where this window lives
-
- Title DC.B 'Slider ',0
- CNOP 0,2
- Letters DC.B 0,'ONMLKJIHGFEDCBA' easier init like this
- CNOP 0,2
-
- END
-
-